package learning.crf.training;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import learning.crf.model.Model;
import learning.util.SparseVector;

public class CRFParameters {

	// a feature weight vector for each transition
	public SparseVector[][] transitionParameters;
	
	public Model model;
	
	public void sum(CRFParameters p, float factor) {
		for (int i=0; i < transitionParameters.length; i++)
			for (int j=0; j < transitionParameters[i].length; j++)
				transitionParameters[i][j] = 
					SparseVector.sum(transitionParameters[i][j], p.transitionParameters[i][j], factor);
	}
	
	public void reset() {
		if (transitionParameters == null) {
			transitionParameters = new SparseVector[model.numStates][model.numStates];
			for (int i=0; i < model.numStates; i++)
				for (int j=0; j < model.numStates; j++)
					transitionParameters[i][j] = new SparseVector();
		}
		
		for (int i=0; i < transitionParameters.length; i++)
			for (int j=0; j < transitionParameters[i].length; j++)
				transitionParameters[i][j].num = 0;
	}

	public void serialize(OutputStream os) 
		throws IOException {
		DataOutputStream dos = new DataOutputStream(os);
		dos.writeInt(model.numStates);
		for (int i=0; i < model.numStates; i++) {
			for (int j=0; j < model.numStates; j++) {
				this.transitionParameters[i][j].serialize(os);
			}
		}		
	}
	
	public void deserialize(InputStream is) 
		throws IOException {
		DataInputStream dis = new DataInputStream(is);
		int numStates = dis.readInt();
		this.model = new Model(numStates-1);
		this.transitionParameters = new SparseVector[numStates][numStates];
		for (int i=0; i < numStates; i++) {
			for (int j=0; j < numStates; j++) {
				this.transitionParameters[i][j] = new SparseVector();
				this.transitionParameters[i][j].deserialize(is);
			}
		}
	}
}
